<?php

abstract class Model {

    private $_table;
    private $_primary_key;
    public $_db;

    function __construct($table, $primary_key = 'id') {
        $this->_table = $table;
        $this->_primary_key = $primary_key;
        $this->_db = Database::getInstance();
    }

    function selectAll() {
        $result = $this->_db->query("SELECT * from " . $this->_table, PDO::FETCH_OBJ);
        return $result->fetchAll();
    }

    /**
     * 
     * @param string|array $field  all | field_name | array(field_name)
     * @param array $cond  condition array()  operation = seulement
     * @param PDO:: $mode  OBJ ou array
     * @param bool $all donner sous forme de tableau mm si c'est unique
     * @param array $attribut order, limit
     * @return objet_ou_array
     */
    public function select($field, $cond = NULL, $mode = PDO::FETCH_OBJ, $all = false, $attribut = array()) {
        // construction de la requête
        if (is_array($field)) {
            $sql = "SELECT " . implode(',', $field);
        } elseif ($field == 'all') {
            $sql = "SELECT * ";
        } else {
            $sql = "SELECT " . $field;
        }
        $sql .= " FROM `" . $this->_table . "`";

        if (is_array($cond)) {
            $sql .= " WHERE ";
            $i = 0;
            foreach ($cond as $key => $value) {
                $sql .= ($i != 0) ? " AND " : '';
                $sql .= $key . " = '" . $value . "'";
                $i++;
            }
        }

        if (isset($attribut['order'])) {
            $sql .= ' ORDER BY ' . $attribut['order'];
        }
        if (isset($attribut['limit'])) {
            $sql .= ' LIMIT ' . $attribut['limit'];
        }

//        print $sql;
        $result = $this->_db->query($sql, $mode);
        if ($result) {

            if ($result->rowCount() == 1 && $all == false) {
                return $result->fetch();
            } else {
                return $result->fetchAll();
            }
        }else{
            return null;
        }
    }

    /**
     *
     * @param array $params tableau associatif type :   nom_de_champ => valeur
     */
    public function insert($params) {
        $sql = 'INSERT INTO `' . $this->_table . '`';
        $keys = $values = array();
        foreach ($params as $key => $value) {
            $keys[] = $key;
            $bind_keys[] = ':' . $key;
            $values[] = $value;
        }
        $sql .= '(' . implode(',', $keys) . ')';
        $sql .= ' VALUES (' . (implode(',', $bind_keys)) . ')';

        $stmt = $this->_db->prepare($sql);
        $nb = count($values);
        for ($i = 0; $i < $nb; $i++) {
            $stmt->bindValue($bind_keys[$i], $values[$i]);
//            var_dump(array($bind_keys[$i],$values[$i]));
        }
//            print $sql;
        try {
            $stmt->execute();
            return $this->_db->lastInsertId();
        } catch (Exception $e) {
            print $e->getMessage();
            return false;
        }
    }

    public function update($params, $cond) {
        $sql = 'UPDATE `' . $this->_table . '`';
        $keys = $values = array();
        foreach ($params as $key => $value) {
            $keys[] = $key . " = :$key";
            $bind_keys[] = ":$key";
            $values[] = $value;
        }
        $sql .= ' SET ' . implode(',', $keys);
        if (is_array($cond)) {
            $sql .= " WHERE ";
            $i = 0;
            foreach ($cond as $key => $value) {
                $sql .= ($i != 0) ? " AND " : '';
                $sql .= $key . " = '" . $value . "'";
                $i++;
            }
        }

        $stmt = $this->_db->prepare($sql);
        $nb = count($values);
//        print $sql;
        for ($i = 0; $i < $nb; $i++) {
            $stmt->bindValue($bind_keys[$i], $values[$i]);
//           var_dump($bind_keys,$values);
        }
        try {
            $stmt->execute();
        } catch (Exception $e) {
            print $e->getMessage();
        }
    }

}